home *** CD-ROM | disk | FTP | other *** search
/ Mac Magazin/MacEasy 1 / Mac Magazin and MacEasy Magazine CD - Issue 01.iso / Sharewarebibliothek / Powermac / C64 / SOURCE / BWVic.c < prev    next >
Text File  |  1994-06-06  |  6KB  |  276 lines

  1. /*
  2.     Commodore 64 Emulator v0.4      Earle F. Philhower III 
  3.     Copyright (C) 1993-4            (st916w9r@dunx1.ocs.drexel.edu)
  4.  
  5.     This program is free software; you can redistribute it and/or modify
  6.     it under the terms of the GNU General Public License as published by
  7.     the Free Software Foundation; either version 2 of the License, or
  8.     (at your option) any later version.
  9.  
  10.     This program is distributed in the hope that it will be useful,
  11.     but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.     MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.     GNU General Public License for more details.
  14.  
  15.     You should have received a copy of the GNU General Public License
  16.     along with this program; if not, write to the Free Software
  17.     Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  18. */
  19.  
  20. #include "Processor.h"
  21. #include "Memory.h"
  22. #include "Error.h"
  23. #include "Resources.h"
  24. #include "VIC.h"
  25.  
  26.  
  27. /* This FastDraw macro courtesy of Peter Creath <peterc@gnu.ai.mit.edu> */
  28. /* It's much faster than my original "FastDraw" which was a misnomer */
  29. #define FastDraw(a, b, c) \
  30. { \
  31.     thisLine=(char**)&(lineStart[(word)((a)<<3)]); \
  32.     theseDefs=(char*)(VICCharDefs+(word)((c)<<3)); \
  33.     *(*thisLine++ + b)=*theseDefs++; \
  34.     *(*thisLine++ + b)=*theseDefs++; \
  35.     *(*thisLine++ + b)=*theseDefs++; \
  36.     *(*thisLine++ + b)=*theseDefs++; \
  37.     *(*thisLine++ + b)=*theseDefs++; \
  38.     *(*thisLine++ + b)=*theseDefs++; \
  39.     *(*thisLine++ + b)=*theseDefs++; \
  40.     *(*thisLine++ + b)=*theseDefs++; \
  41. }
  42.  
  43. static byte *lineStart[200];
  44. static Rect leftRect, rightRect, topRect, botRect, sprRect;
  45. static BitMap spriteMap, VICMap, fullMap;
  46. static GrafPtr spriteGraf;
  47.  
  48. extern Rect bwWindRect, bwFullRect;
  49.  
  50. static Ptr NewBitMap(BitMap *theBits, Rect *rp)
  51. {
  52.     theBits->rowBytes=((rp->right-rp->left+15)/16)*2;
  53.     theBits->baseAddr=(Ptr)GetMemory(theBits->rowBytes*(rp->bottom-rp->top));
  54.     theBits->bounds=*rp;
  55.     return(theBits->baseAddr);
  56. }
  57.  
  58. int BWVICInitialize()
  59. {
  60.     int row;
  61.  
  62.     SetRect(&bwFullRect, 0, 0, 320, 200);
  63.     SetRect(&leftRect, 0, 0, 7, 200);
  64.     SetRect(&rightRect, 320-8, 0, 320, 200);
  65.     SetRect(&topRect, 0, 0, 320, 4);
  66.     SetRect(&botRect, 0, 200-4, 320, 200);
  67.     SetRect(&sprRect, 0, 0, 24, 21);
  68.     
  69.     BWVICWind=GetNewWindow(kBWVIC, nil, (WindowPtr)-1L);
  70.     if (BWVICWind==nil) return(kMissingResource);
  71.     SetWRefCon(BWVICWind, kVICWindow);
  72.     
  73.     
  74.     if (NewBitMap(&spriteMap, &sprRect)==0) return kOutOfMemory;
  75.     if (NewBitMap(&VICMap, &bwFullRect)==0) return kOutOfMemory;
  76.     if (NewBitMap(&fullMap, &bwFullRect)==0) return kOutOfMemory;
  77.  
  78.     for (row=0; row<200; row++)
  79.         lineStart[row]=(byte *)VICMap.baseAddr+40*row;
  80.  
  81.     return(kNoError);
  82. }
  83.  
  84. void ShowBWVIC()
  85. {
  86.     SelectWindow(BWVICWind);
  87.     ShowWindow(BWVICWind);
  88.     SetPort(BWVICWind);
  89. }
  90.  
  91. void HideBWVIC()
  92. {
  93.     HideWindow(BWVICWind);
  94. }    
  95.  
  96. static void DrawSprites()
  97. {
  98.     byte spriteNum, row, *spb0, *spb1, *spb2;
  99.     word xpos, ypos, addr0, addr1, addr2;
  100.     Rect t;
  101.     BitMap saveMap;
  102.     
  103.     CopyBits(&VICMap,&fullMap,&bwFullRect,&bwFullRect,srcCopy,nil);
  104.     saveMap = qd.thePort->portBits;
  105.     SetPortBits(&spriteMap);
  106.     for (spriteNum=0; spriteNum<8; spriteNum++)
  107.         if (VICRegister[0x15]&(1<<spriteNum))
  108.         {
  109.             xpos = (VICRegister[0x00+spriteNum*2]-24);
  110.             xpos += (VICRegister[0x10]&(1<<spriteNum))?256:0;
  111.             ypos = VICRegister[0x01+spriteNum*2]-50;
  112.             
  113.             t.top=ypos;
  114.             t.left=xpos;
  115.             t.right=t.left+24+((VICRegister[0x1d]&(1<<spriteNum))?24:0);
  116.             t.bottom=t.top+21+((VICRegister[0x17]&(1<<spriteNum))?21:0);
  117.             
  118.             addr0 = VICAddrBase+RAM[VICScreenPage+1016+spriteNum]*64;
  119.             addr1=addr0+1;
  120.             addr2=addr0+2;
  121.             
  122.             spb0=(byte *)spriteMap.baseAddr;
  123.             spb1=spb0+1;
  124.             spb2=spb0+2;
  125.             
  126.             for (row=0; row<21; row++)
  127.             {
  128.                 spb0[row<<2]=RAM[addr0+row*3];
  129.                 spb1[row<<2]=RAM[addr1+row*3];
  130.                 spb2[row<<2]=RAM[addr2+row*3];
  131.             }
  132.             CopyBits(&spriteMap,&fullMap,&sprRect,&t,srcOr,nil);
  133.         }
  134.     SetPortBits(&saveMap);
  135.     SetPort(BWVICWind);
  136. }
  137.  
  138. static void DrawTextScreen(byte total)
  139. {
  140.     word chr;
  141.     byte row, col;
  142.     register char **thisLine;
  143.     register char *theseDefs;
  144.     BitMap saveMap;
  145.     
  146.     row=col=0;
  147.     saveMap=qd.thePort->portBits;
  148.     SetPortBits(&VICMap);
  149.     
  150.     if (VICRegister[0x11]&32)
  151.     {
  152.         /* Draw Hi-Res screen *always* since that only makes sense */
  153.         VICCharDefs=RAM+VICAddrBase+((VICRegister[0x18]&8)?8192:0);
  154.         for (chr=0; chr<1000; chr++)
  155.         {
  156.             FastDraw(row,col,chr);
  157.             col++;
  158.             if (++col>39)
  159.             {
  160.                 col=0;
  161.                 row++;
  162.             }
  163.         }
  164.     }
  165.     else
  166.     {
  167.         /* Draw the text screen */
  168.         if (total)
  169.             /* Draw every single character */
  170.             for (chr=0; chr<1000; chr++)
  171.             {
  172.                 FastDraw(row,col,RAM[chr+VICScreenPage]);
  173.                 VICText[chr]=RAM[chr+VICScreenPage];
  174.                 if (++col>39)
  175.                 {
  176.                     col=0;
  177.                     row++;
  178.                 }
  179.             }
  180.         else
  181.             for (chr=0;chr<1000;chr++)
  182.             {
  183.                 if (VICText[chr]!=RAM[chr+VICScreenPage])
  184.                 {
  185.                     FastDraw(row,col,RAM[chr+VICScreenPage]);
  186.                     VICText[chr]=RAM[chr+VICScreenPage];
  187.                 }
  188.                 if (++col>39)
  189.                 {
  190.                     col=0;
  191.                     row++;
  192.                 }
  193.             }
  194.     }
  195.     SetPortBits(&saveMap);
  196. }
  197.  
  198. static void DrawBorders()
  199. {
  200.     BitMap saveMap;
  201.     
  202.     saveMap=qd.thePort->portBits;
  203.     SetPortBits(&VICMap);
  204.     if ((VICRegister[0x16]&8)==0)
  205.     {
  206.         FillRect(&leftRect, (ConstPatternParam)&qd.black);
  207.         FillRect(&rightRect, (ConstPatternParam)&qd.black);
  208.     }
  209.     if ((VICRegister[0x11]&8)==0)
  210.     {
  211.         FillRect(&botRect, (ConstPatternParam)&qd.black);
  212.         FillRect(&topRect, (ConstPatternParam)&qd.black);
  213.     }
  214.     SetPortBits(&saveMap);
  215. }
  216.  
  217. static void CopyTextToScreen()
  218. {
  219.     SetPort(BWVICWind);
  220.     CopyBits(&VICMap, &(BWVICWind->portBits), &bwFullRect, &bwWindRect, srcCopy, nil);
  221. }
  222.  
  223. static void CopySpritesToScreen()
  224. {
  225.     SetPort(BWVICWind);
  226.     CopyBits(&fullMap, &(BWVICWind->portBits), &bwFullRect, &bwWindRect, srcCopy, nil);    
  227. }
  228.  
  229. static void BlankScreen()
  230. {
  231.     BitMap saveMap;
  232.     
  233.     saveMap = qd.thePort->portBits;
  234.     SetPortBits(&VICMap);
  235.     FillRect(&bwFullRect, (PatPtr)&qd.gray);
  236.     SetPortBits(&saveMap);
  237.     CopyTextToScreen();
  238. }
  239.  
  240. void BWTotalRedrawVIC()
  241. {
  242.     SetPort(BWVICWind);    
  243.     if ((VICRegister[0x11]&16)==0)
  244.     {
  245.         BlankScreen();
  246.         return;
  247.     }
  248.     DrawTextScreen(1);
  249.     DrawBorders();
  250.     if (VICRegister[0x15])
  251.     {
  252.         DrawSprites();
  253.         CopySpritesToScreen();
  254.     }
  255.     else CopyTextToScreen();
  256. }
  257.  
  258. void BWRedrawVIC()
  259. {
  260.     SetPort(BWVICWind);
  261.     if ((VICRegister[0x11]&16)==0)
  262.     {
  263.         BlankScreen();
  264.         return;
  265.     }
  266.     DrawTextScreen(0);
  267.     DrawBorders();
  268.     if (VICRegister[0x15])
  269.     {
  270.         DrawSprites();
  271.         CopySpritesToScreen();
  272.     }
  273.     else CopyTextToScreen();
  274. }
  275.  
  276.